package com.fatcat.easybuy.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.fatcat.easybuy.annotaion.CheckPermission;
import com.fatcat.easybuy.config.AlipayConfig;
import com.fatcat.easybuy.pojo.EasyBuyOrder;
import com.fatcat.easybuy.service.AliPayService;
import com.fatcat.easybuy.service.EasyBuyOrderService;
import com.fatcat.easybuy.service.EasyBuyProductService;
import com.fatcat.easybuy.util.ResponseResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 郝秦毅
 * @since 2025/9/8 14:31
 */
@RestController
@RequestMapping("/alipay")
public class AlipayController {

    @Autowired
    private AlipayConfig alipayConfig;
    @Autowired
    private EasyBuyOrderService easyBuyOrderService;

    @Autowired
    private AliPayService aliPayService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    private static final Logger LOGGER = LoggerFactory.getLogger(AlipayController.class);
    private static final String ORDER_EXPIRE_KEY_PREFIX = "order:";

    @PostMapping("/pay")
    @CheckPermission({"0", "1"})
    public ResponseResult pay(@RequestBody Map<String, String> params, HttpServletResponse response) throws AlipayApiException {
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.getGatewayUrl(), alipayConfig.getAppId(), alipayConfig.getMerchant_private_key(), alipayConfig.getFormat(), alipayConfig.getCharset(), alipayConfig.getAlipay_public_key(), alipayConfig.getSignType());
        AlipayTradePagePayRequest alipayTradePagePayRequest = new AlipayTradePagePayRequest();
        alipayTradePagePayRequest.setNotifyUrl(alipayConfig.getNotify_url());
        alipayTradePagePayRequest.setReturnUrl(alipayConfig.getReturn_url());
        // 检查订单是否存在
        EasyBuyOrder order = easyBuyOrderService.getOrderBySerialNumber(params.get("outTradeNo"));
        if (order == null) {
            return ResponseResult.error("订单不存在");
        }
        // 检查订单是否已处理
        if (order.getStatus() == 2) {
            return ResponseResult.success("订单已支付,无需重复支付");
        }

        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
        model.setProductCode("FAST_INSTANT_TRADE_PAY");
        //订单号
        model.setOutTradeNo(params.get("outTradeNo"));
        EasyBuyOrder easyBuyOrder = easyBuyOrderService.getOrderBySerialNumber(params.get("outTradeNo"));
        //订单金额
        model.setTotalAmount(easyBuyOrder.getCost().toString());
        //订单标题
        model.setSubject(params.get("subject"));
        //商户id
        model.setStoreId(params.get("storeId"));
        //绝对超时时间
        model.setTimeoutExpress("20m");

        alipayTradePagePayRequest.setBizModel(model);

        AlipayTradePagePayResponse pagePayResponse = alipayClient.pageExecute(alipayTradePagePayRequest, "post");
        //获得返回体
        String pageRedirectionData = pagePayResponse.getBody();

        return ResponseResult.success().add("form", pageRedirectionData);
    }

    /**
     * 处理订单退款请求
     */
    @PostMapping("/orderRefund")
    @CheckPermission({"0", "1"})
    public ResponseResult refund(@RequestBody Map<String, String> params) {
        // 解析参数
        Long orderId = Long.parseLong(params.get("orderId"));
        Double refundAmount = Double.parseDouble(params.get("refundAmount"));
        String refundReason = params.get("refundReason");

        // 校验订单是否存在
        EasyBuyOrder order = easyBuyOrderService.getOrderById(orderId);
        if (order == null) {
            return ResponseResult.error("订单不存在");
        }

        // 校验订单状态（仅已付款订单可退款）
        if (order.getStatus() != 2) { // 假设2=已付款
            return ResponseResult.error("仅已付款订单可申请退款");
        }
        // 校验订单状态（仅已付款订单可退款）
        if (order.getStatus() == 4) { // 4 = 已退款
            LOGGER.info("订单已退款，无需重复申请，订单 ID：{}", orderId);
            return ResponseResult.success("订单已退款，无需重复申请");
        }
        // 校验退款金额（不超过订单总金额）
        Double orderAmount = order.getCost(); // 订单总金额
        if (refundAmount <= 0 || refundAmount > orderAmount) {
            return ResponseResult.error("退款金额必须大于0且不超过订单总金额（" + orderAmount + "元）");
        }
// 调用支付宝前
        LOGGER.info("发起退款请求，订单号：{}，退款金额：{}", order.getSerialNumber(), refundAmount);
        //调用支付宝退款接口
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.getGatewayUrl(), alipayConfig.getAppId(), alipayConfig.getMerchant_private_key(), alipayConfig.getFormat(), alipayConfig.getCharset(), alipayConfig.getAlipay_public_key(), alipayConfig.getSignType());

        // 构建退款请求参数
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();
        model.setOutTradeNo(order.getSerialNumber()); // 商户订单号
        model.setTradeNo(order.getAlipayTradeNo()); // 支付宝交易号
        model.setRefundAmount(refundAmount.toString()); // 退款金额
        model.setRefundReason(refundReason); // 退款原因
//        model.setOutRequestNo(order.getAlipayTradeNo() + System.currentTimeMillis());// 退款请求号
        model.setOutRequestNo(order.getAlipayTradeNo());// 退款请求号
        request.setBizModel(model);

        // 执行退款请求
        AlipayTradeRefundResponse response = null;
        try {
            response = alipayClient.execute(request);
            // 退款失败：返回支付宝错误信息
            if (response.getCode().equals("40004")) {
                return ResponseResult.error("交易已过期，无法退款");
            }
            // 退款失败：返回支付宝错误信息
            if (response.getCode().equals("20000")) {
                return ResponseResult.error("系统异常稍后重试");
            }
            // 根据支付宝响应结果处理
            if (response.isSuccess()) {
                // 支付宝响应后
                LOGGER.info("支付宝退款响应：code={}, msg={}, subCode={}, subMsg={}", response.getCode(), response.getMsg(), response.getSubCode(), response.getSubMsg());
                // 退款成功
                if (aliPayService.handleRefundNotify(order.getSerialNumber())) {
                    LOGGER.info("订单状态更新结果：{}，订单号：{}", order.getStatus(), order.getSerialNumber());
                    return ResponseResult.success("退款成功");
                } else {
                    return ResponseResult.error("更新订单状态失败");
                }
            } else {
                // 退款失败：返回支付宝错误信息
                return ResponseResult.error("退款失败：" + response.getMsg());
            }
        } catch (AlipayApiException e) {
            LOGGER.error("支付宝退款请求失败，订单号：{}，异常信息：{}", order.getSerialNumber(), e.getMessage());
            return ResponseResult.error("支付宝退款请求失败");
        }
    }

    /**
     * 支付宝异步通知处理（主要用于更新订单状态）
     */
    @PostMapping("/notify_url")
    public ResponseResult notifyUrl(HttpServletRequest request) throws AlipayApiException {
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestMap = request.getParameterMap();

        // 解析请求参数
        for (Iterator<String> iter = requestMap.keySet().iterator(); iter.hasNext(); ) {
            String name = iter.next();
            String[] values = requestMap.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }

        // 验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipay_public_key(), alipayConfig.getCharset(), alipayConfig.getSignType());

        if (!signVerified) {
            // 签名验证失败
            LOGGER.error("支付宝签名验证失败，参数: {}", params);
            return ResponseResult.error("支付宝签名验证失败");
        }

        // 商户订单号
        String outTradeNo = params.get("out_trade_no");
        // 支付宝交易号
        String tradeNo = params.get("trade_no");
        // 交易状态
        String tradeStatus = params.get("trade_status");

        LOGGER.debug("收到支付宝异步通知，订单号: {}, 交易号: {}, 状态: {}", outTradeNo, tradeNo, tradeStatus);

        // 检查订单是否存在
        EasyBuyOrder order = easyBuyOrderService.getOrderBySerialNumber(outTradeNo);
        if (order == null) {
            LOGGER.error("支付宝异步通知处理失败，订单不存在，订单号: {}", outTradeNo);
            return ResponseResult.error("订单不存在");
        }

        // 检查订单是否已处理
        if (order.getStatus() == 2) {
            return ResponseResult.success("订单已支付,无需重复支付");
        }

        // 根据交易状态处理订单
        if (tradeStatus.equals("TRADE_SUCCESS")) {

            if (aliPayService.handlePayNotify(outTradeNo, tradeNo)) {
                // 删除 Redis 中的订单过期键
                String redisKey = ORDER_EXPIRE_KEY_PREFIX + order.getId();
                redisTemplate.delete(redisKey);
                LOGGER.info("订单支付成功，订单号: {}, 支付宝交易号: {}", outTradeNo, tradeNo);
                return ResponseResult.success("订单支付成功");
            } else {
                LOGGER.error("订单支付成功但更新状态失败，订单号: {}", outTradeNo);
                return ResponseResult.error("订单支付成功,数据库更新失败");
            }
        } else if (tradeStatus.equals("TRADE_FINISHED")) {
            LOGGER.debug("交易已结束，订单号: {}", outTradeNo);
            return ResponseResult.success("交易已结束");
        } else {
            LOGGER.debug("交易状态未处理，状态: {}, 订单号: {}", tradeStatus, outTradeNo);
            return ResponseResult.success("交易状态已接收");
        }

    }

    /**
     * 支付宝同步回调（支付完成后跳回前端）
     */
    @GetMapping("/return_url")
    public void returnUrl(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException, IOException {
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestMap = request.getParameterMap();

        // 解析请求参数
        for (Iterator<String> iter = requestMap.keySet().iterator(); iter.hasNext(); ) {
            String name = iter.next();
            String[] values = requestMap.get(name);
            String valueStr = Arrays.stream(values).collect(Collectors.joining(","));
            params.put(name, valueStr);
        }

        // 验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipay_public_key(), alipayConfig.getCharset(), alipayConfig.getSignType());

        String outTradeNo = params.get("out_trade_no");
        String tradeStatus = params.get("trade_status");
        String redirectUrl = "http://localhost:8081/alipay/AlipayCallbackView";

        LOGGER.debug("收到支付宝同步回调，订单号: {}, 状态: {}", outTradeNo, tradeStatus);

        if (signVerified) {
            try {
                // 检查订单状态
                EasyBuyOrder order = easyBuyOrderService.getOrderBySerialNumber(outTradeNo);

                if (order != null && order.getStatus() == 2) {
                    // 订单已支付成功
                    LOGGER.info("订单支付成功，同步回调跳转，订单号: {}", outTradeNo);
                } else if ("TRADE_SUCCESS".equals(tradeStatus)) {
                    // 支付成功但状态未更新（可能异步通知还未处理）
                    LOGGER.debug("支付成功但状态未更新，订单号: {}", outTradeNo);
                } else {
                    // 支付未成功
                    LOGGER.debug("支付未成功，订单号: {}", outTradeNo);
                }

            } catch (Exception e) {
                LOGGER.error("同步回调处理异常，订单号: " + outTradeNo, e);
            }
        } else {
            // 签名验证失败
            LOGGER.error("支付宝同步回调签名验证失败，参数: {}", params);
        }
        // 重定向到前端页面
        response.sendRedirect(redirectUrl);
    }

}
